Fix coroutines reporting corrupted line numbers #106758
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR fixes corrupted line numbers for coroutines in the debugger and backtrace. I discovered this issue while testing #91006 for sentry-godot use case. The issue is described in detail here:
The changes are deliberately minimal -- just to fix this problem. Please let me know if you think we should take a different approach.
Fixes #106489
Explanation
Why it happens
call():linevariable is local, andenter_function()is passed a reference to this variable.enter_function()initializesCallLevelwith a pointer to thelinevariable (which is scoped tocall()).linevariable is continuously updated during GDScript function execution using OPCODE_LINE operation.call()is exited, andlineis popped off the stack, but theCallLevelinstance still lives on due to specifics of the resumed function execution (exit_function()isn't called yet).CallLevelframes overstayed the lifetime of theirlinevariables.Conclusion: Because
CallLeveloutlivescall()'s scope for resumed coroutines,CallLevel::linepointer can sometimes point to heaven-knows-what.Hey @mihe, do you think this could be the reason why the initially proposed reversed linked-list call stack implementation crashed in coroutine unit tests? (#91006)
Explaining on example
Consider this code:
Output:
Notice that the backtrace reports crazy line numbers, and how call(f1) already exited, but the associated CallLevel frame lingers slightly longer in the end (exit_function). This only happens for resumed functions.